/**
 * @class Cube.Loader
 * 
 * Cube.Loader is responsible for loading classes dynamically. The {@link Cube.Loader#require Cube.Loader.require} and {@link Cube.Loader#requires Cube.Loader.requires} methods
 * are generally not called from the Loader class. Use the shorthands {@link G#require Cube.require} and {@link G#requires Cube.requires} instead.
 * 
 * ### Usage ###
 * To require only one class:
 * 
 * 	Cube.require('Cube.window.Window');
 *
 * To require multiple classes at once:
 * 
 * 	Cube.requires(['Cube.window.Window', 'Cube.another.Class', 'Cube.another.Class2']);
 * 
 * 
 * 
 * @singleton 
 */
(function() {

	Cube.Loader = {

		/**
		 * Require multiple classes
		 * 
		 * @param {Array} classes
		 */
		requires: function(classes) {
			for (i in classes)
			{
				Cube.Loader.require(classes[i]);
			}
		},

		/**
		 * Require Class
		 * 
		 * @param {String} className
		 */
		require: function(className) {
			if (!Cube.ClassManager.isDefined(className))
			{
				if (!Cube.Loader.injectScript(className))
				{
					Cube.Logger.error("Could not dynamically load: " + className);
				}
			}
		},

		/**
		 * Get contents of file
		 *  
 	 	 * @param {String} className
 	 	 * @return {String} Contents of file
		 */
		getFile: function(path, module)
		{
			var returnValue = false;
			
			var root = Cube.Loader.getRootFromClassName(module.$className);
			
			if (!root)
			{
				Cube.Logger.error("[Cube.Loader] Could not get file " + path + ". Root path wasn't found. Make sure the module object is correct!");
			}
			
			Cube.Ajax.request({
				url: root + path,
				type: 'GET',
				async: false,
				cache: Cube.config.cache,
				success: function(response) {
					returnValue = response;
				}
			});
			
			return returnValue;
		},
		
		/**
		 * Inject script
		 * 
		 * @param {String} className
		 * @param {Boolean} contents
		 */
		injectScript: function(className) {
			var parts = className.split('.'),
				returnValue = false;

			for (i in Cube.config.paths)
			{
				if (i == parts[0])
				{
					parts[0] = Cube.config.paths[i];
					parts[0] = parts[0].substr(0, parts[0].length - 1);
				}
			}

			var file = parts.join('/') + '.js';
			
			Cube.Ajax.request({
				url: file,
				type: 'GET',
				async: false,
				cache: Cube.config.cache,
				success: function(response, xhr) {
					eval(response);
					returnValue = true;
				}
			}, window);
			
			return returnValue;
		},
		
		getRootFromClassName: function(className)
		{
			var module = className.split('.')[0];
			
			for (i in Cube.config.paths)
			{
				if (module == i)
				{
					return Cube.config.paths[i];
				}
			}
			
			return false;
		}

	};

	/**
     * Convenient alias of {@link Cube.Loader#require}. Please see the introduction documentation of
     * {@link Cube.Loader} for examples.
     * 
     * @member Cube
     * @method require
     */
	Cube.require 	= Cube.Loader.require;

	/**
	 * Alias of {@link Cube.Loader#require}. Please see the documentation of {@link Cube.Loader} for more info.
	 * 
	 * @member Cube
	 * @method requires 
	 */
	Cube.requires 	= Cube.Loader.requires;

})();